from flask import request, jsonify, current_app, make_response
# 使用蓝图对象 导入蓝图
from . import passport_blue
# 导入captche扩展 生成图片验证码
from info.utils.captcha.captcha import captcha
# 导入自定义状态码
from info.utils.response_code import RET
# 导入redis实例 | 导入常量的配置信息文件
from info import redis_store, constants
# 导入正则模块
import re, random
# 导入云通信扩展
from info.libs.yuntongxun.sms import CCP


# 生成图片代码视图函数
@passport_blue.route('/image_code')
def generate_image_code():
    '''
    生成图片代码函数
        1. 获取参数 获取UUID
        2. 使用request 获取查询字符串参数 args
        3. 判断参数是否存在
    :return:
    '''
    # 获取参数(image_code_id)UUID
    image_code_id = request.args.get('image_code_id')

    # 如果参数不存在 直接return
    if not image_code_id:
        # 将错误信息响应给前端
        return jsonify(errno=RET.PARAMERR, errmsg='参数缺失')
    # 如果参数存在 生成图片验证码
    name, text, image = captcha.generate_captcha()

    # 存储图片验证码的内容到redis中
    try:
        redis_store.setex('imageCode_' + image_code_id, constants.IMAGE_CODE_REDIS_EXPIRES, text)
    except Exception as e:
        # 出现异常记录项目日志
        current_app.logger().error(e)
        # 出现异常直接return给前端一个提示信息
        return jsonify(errno=RET.DBERR, errmsg='保存数据错误')
    else:
        # 返回前端图片路径
        response = make_response(image)

        # 返回响应 设置响应的类型为
        response.headers['Context-Type'] = 'image/jpg'
        return response


# 发送短信视图函数
@passport_blue.route('/sms_code', methods=['POST'])
def send_sms_code():

    # 获取参数 手机号 用户输入的验证码 UUID
    mobile = request.json.get('mobile')
    image_code = request.json.get('image_code')
    image_code_id = request.json.get('image_code_id')

    # 检查参数
    if not all([mobile, image_code, image_code_id]):
        # 如果参数不完整 直接return
        return jsonify(errno=RET.PARAMERR, errmsg='参数不完整')

    # 如果参数完整再进行进一步校验 使用正则校验手机号
    if not re.match(r'^1[3456789]\d{9}$', mobile):
        # 如果手机号匹配失败 直接return
        return jsonify(errno=RET.PARAMERR, errmsg='手机号格式错误')

    # 从redis获取真是的图片验证码
    try:
        # 获取
        real_image_code = redis_store.get('imageCode_' + image_code_id)
    except Exception as e:
        # 如果获取时发生异常
        current_app.logger().error(e)
        return jsonify(errno=RET.DBERR, errmsg='获取数据失败')

    # 判断获取结果
    if not real_image_code:
        return jsonify(errno=RET.DATAERR, errmsg='图片验证码过期')

    # 删除redis中的图片验证码 因为图片验证码只能比较一次
    try:
        redis_store.delete('imageCode_' + image_code_id)
    except Exception as e:
        current_app.logger().error(e)

    # 比较图片验证码是否正确
    if real_image_code.lower() != image_code.lower():
        return jsonify(errno=RET.DATAERR, errmsg='图片验证码不一致')

    # 生成短信的六位数
    sms_code = '%06d' % random.randint(0, 999999)

    try:
        # 存入redis中 key拼接手机号
        redis_store.setex('SMSCode_' + mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
    except Exception as e:
        current_app.logger().error(e)
        return jsonify(errno=RET.DBERR, errmsg='保存数据失败')

    # 调用云通讯发送短信
    try:
        ccp = CCP()
        result = ccp.send_template_sms(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES / 60], 1)
    except Exception as e:
        current_app.logger().error(e)
        return jsonify(errno=RET.THIRDERR, errmsg='发送短信失败')

    # 判断result是否成功
    if result == 0:
        return jsonify(errno=RET.OK, errmsg='发送成功')
    else:
        return jsonify(errno=RET.THIRDERR, errmsg='发送失败')

